package com.jxl.coreplay.flash
{
	import fl.core.InvalidationType;
	import fl.core.UIComponent;
	
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.Dictionary;

	public class View extends UIComponent
	{
		protected var _debugRect:Boolean				= false;
		protected var debugDrawSprite:Sprite;
		
		public function get debugRect():Boolean { return _debugRect; }
		public function set debugRect(val:Boolean):void
		{
			debugRect = val;
			invalidateSize();
		}
		
		public function View():void
		{
			super();
		}
		
		protected function invalidateProperties():void
		{
			invalidate(InvalidationType.DATA);
		}
		
		protected function invalidateSize():void
		{
			invalidate(InvalidationType.SIZE);
		}
		
		protected override function draw():void
		{
			if(isInvalid(InvalidationType.DATA) == true)
			{
				commitProperties();
			}
			
			if(isInvalid(InvalidationType.SIZE) == true)
			{
				size();
			}
			
			super.draw();
		}
		
		protected function commitProperties():void
		{
			
		}
		
		protected function size():void
		{
			if(debugRect == true)
			{
				if(debugDrawSprite == null)
				{
					debugDrawSprite = new Sprite();
					addChild(debugDrawSprite);
					setChildIndex(debugDrawSprite, numChildren - 1);
				}
				
				debugDrawSprite.x = debugDrawSprite.y = 0;
				var dgh:Graphics = debugDrawSprite.graphics;
				dgh.clear();
				dgh.lineStyle(0, 0xFF0000, 1);
				dgh.drawRect(0, 0, _width, _height);
				dgh.endFill();
			}
			else
			{
				if(debugDrawSprite != null)
				{
					debugDrawSprite.graphics.clear();
					this.removeChild(debugDrawSprite);
					debugDrawSprite = null;
				}
			}
		}
		
		public function removeAllChildren():void
		{
			var len:int = numChildren;
			while(len--)
			{
				removeChildAt(len);
			}
		}
		
		// HACK
		// Found here:
		// http://www.kirupa.com/forum/showthread.php?t=287632
		// modified to use added_to_stage
		override protected function callLater(fn:Function):void {
            callLaterMethods[fn] = true;
            if (stage != null) {
                stage.addEventListener(Event.RENDER,callLaterDispatcher,false,0,true);
                stage.invalidate();                
            } else {
                addEventListener(Event.ADDED_TO_STAGE,callLaterDispatcher,false,0,true);
            }
        }
        
        private function callLaterDispatcher(event:Event):void {
            if (event.type == Event.ADDED_TO_STAGE) {
                removeEventListener(Event.ADDED_TO_STAGE,callLaterDispatcher);
                // now we can listen for render event:
                stage.addEventListener(Event.RENDER,callLaterDispatcher,false,0,true);
                stage.invalidate();
                
                return;
            } else {
                event.target.removeEventListener(Event.RENDER,callLaterDispatcher);
                if (stage == null) {
                    // received render, but the stage is not available, so we will listen for addedToStage again:
                    addEventListener(Event.ADDED_TO_STAGE,callLaterDispatcher,false,0,true);
                    return;
                }
            }
            var methods:Dictionary = new Dictionary();
            for (var copyMethod:Object in callLaterMethods) {
                methods[copyMethod] = callLaterMethods[copyMethod];
                delete(callLaterMethods[copyMethod]);
            }
            for (var method:Object in methods) {
                method();
            }
        }
		
	}
}